﻿using DZEROPhysicsResultsPages;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using t_TestingLibrary;
using System.IO;
using PaperRenderingInterfaces;
using System.ComponentModel.Composition;
using System.Collections.Generic;
using System.Linq;
using DeepZoomPivotConstructor.PivotLib;

namespace t_DZEROPhysicsResultsPages
{
    
    
    /// <summary>
    ///This is a test class for ScanMasterPageTest and is intended
    ///to contain all ScanMasterPageTest Unit Tests
    ///</summary>
    [TestClass()]
    public class t_ScanMasterPage
    {


        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        // 
        //You can use the following additional attributes as you write your tests:
        //
        //Use ClassInitialize to run code before running the first test in the class
        //[ClassInitialize()]
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}
        //
        //Use ClassCleanup to run code after all tests in a class have run
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //Use TestInitialize to run code before running each test
        //[TestInitialize()]
        //public void MyTestInitialize()
        //{
        //}
        //
        //Use TestCleanup to run code after each test has run
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //
        #endregion

        [TestInitialize]
        public void Setup()
        {
            Utilities.MyClassInit();
        }

        [TestCleanup]
        public void Cleanup()
        {
            Utilities.MyClassDone();
        }

        /// <summary>
        /// Load a file instead of accessing the web.
        /// </summary>
        [Export(typeof(IWebAccess))]
        private class LoadAFile : IWebAccess
        {
            public FileInfo theFileToLoad;
            public string UrlAskedFor { get; set; }

            public string GetUriAsString(Uri whatToLoad)
            {
                UrlAskedFor = whatToLoad.OriginalString;

                return LoadFile(theFileToLoad);
            }

            /// <summary>
            /// Load up the req' file.
            /// </summary>
            /// <param name="finfo"></param>
            /// <returns></returns>
            private string LoadFile(FileInfo finfo)
            {
                if (finfo.Exists)
                {
                    using (var reader = finfo.OpenText())
                    {
                        return reader.ReadToEnd();
                    }
                }
                else
                {
                    return null;
                }
            }


            public DateTime? GetLastModificationTime(Uri whatToCheck)
            {
                return DateTime.Now;
            }
        }

        /// <summary>
        /// Helper class that doesn't actually do any rendering as much as hold onto things.
        /// </summary>
        [Export(typeof(IPaperRenderEngine))]
        class DummyRender : IPaperRenderEngine
        {
            public List<string> addressesRequested = new List<string>();

            public IEnumerable<DeepZoomPivotConstructor.PivotLib.PivotImage> Render(string renderName, string renderAddress)
            {
                if (!addressesRequested.Contains(renderAddress))
                {
                    addressesRequested.Add(renderAddress);
                    PivotImage pm = new PivotImage(null);
                    pm.Name = "HSF1";
                    yield return pm;
                }
            }
        }

        /// <summary>
        ///A test for ScanMasterPage Constructor
        ///</summary>
        [TestMethod]
        public void ScanMasterPageConstructorTest()
        {
            ScanMasterPage target = new ScanMasterPage();
        }

        /// <summary>
        /// Hunt throught the metadata!
        /// </summary>
        /// <typeparam name="T1"></typeparam>
        /// <param name="pmf"></param>
        /// <param name="p"></param>
        /// <returns></returns>
        private T1[] FindMetadata<T1>(PivotImage pmf, string p)
            where T1 : PivotMetadataBase
        {
            var md = from m in pmf
                     where m.Name == p && m.GetType() == typeof(T1)
                     let masType = (T1)m
                     where masType != null
                     select masType;
            return md.ToArray();
        }

        [TestMethod]
        public void TestHiggsPage()
        {
            ScanMasterPage target = new ScanMasterPage();
            var laf = new LoadAFile() { theFileToLoad = new FileInfo("..\\..\\..\\t_DZEROPhysicsResultsPages\\Higgs.html") };
            Utilities.AddPart(laf);
            var rd = new DummyRender();
            Utilities.AddPart(rd);
            Utilities.Compose(target);

            var result = target.Render("http://www-d0.fnal.gov/Run2Physics/WWW/results/higgs.htm");
            var results = result.ToArray();
            Assert.AreEqual(20, results.Count(), "Wrong number of images found!");

            Assert.AreEqual(20, rd.addressesRequested.Count, "Inproper number of requested links!");
            PivotImage pi = results.First();

            Assert.IsTrue(pi.Count() > 0, "Expected some meta data with the image");

            Assert.AreEqual(1, FindMetadata<PivotMetadataURL>(pi, "More Information").Count(), "Expecting 1 links to more information");

            Assert.AreEqual(1, FindMetadata<PivotMetadataString>(pi, "Note Title").Count(), "Expecting a note title!");
        }

        [TestMethod]
        public void TestEWPageForNoFigures()
        {
            ScanMasterPage target = new ScanMasterPage();
            var laf = new LoadAFile() { theFileToLoad = new FileInfo("..\\..\\..\\t_DZEROPhysicsResultsPages\\EW.html") };
            Utilities.AddPart(laf);
            var rd = new DummyRender();
            Utilities.AddPart(rd);
            Utilities.Compose(target);

            var result = target.Render("http://www-d0.fnal.gov/Run2Physics/WWW/results/ew.htm");
            var results = result.ToArray();

            var figTitles = from pvi in results
                            let md = FindMetadata<PivotMetadataString>(pvi, "Note Title")
                            from mdTitle in md
                            select mdTitle.Value;

            Assert.AreEqual(0, figTitles.Count(m => m == "Figures"), "Found some guys titled Figures!");
        }

        /// <summary>
        /// THis is a kludge test - we have some funny html on one of the pages that points to single top results.
        /// </summary>
        [TestMethod]
        public void TestTopForNoAdditionalInfo()
        {
            ScanMasterPage target = new ScanMasterPage();
            var laf = new LoadAFile() { theFileToLoad = new FileInfo("..\\..\\..\\t_DZEROPhysicsResultsPages\\Top.html") };
            Utilities.AddPart(laf);
            var rd = new DummyRender();
            Utilities.AddPart(rd);
            Utilities.Compose(target);

            var result = target.Render("http://www-d0.fnal.gov/Run2Physics/WWW/results/Top.htm");
            var results = result.ToArray();

            var figTitles = from pvi in results
                            let md = FindMetadata<PivotMetadataString>(pvi, "Note Title")
                            from mdTitle in md
                            select mdTitle.Value;

            Assert.AreNotEqual(0, figTitles.Count(), "should have found some titles!");
            Assert.AreEqual(0, figTitles.Count(m => m == "Additional Info"), "Found some guys titled additional Info!");
        }

        /// <summary>
        /// THis is a kludge test - we have some funny html on one of the pages that points to single top results.
        /// </summary>
        [TestMethod]
        public void TestQCDForHTMLMuSymbol()
        {
            ScanMasterPage target = new ScanMasterPage();
            var laf = new LoadAFile() { theFileToLoad = new FileInfo("..\\..\\..\\t_DZEROPhysicsResultsPages\\QCD.html") };
            Utilities.AddPart(laf);
            var rd = new DummyRender();
            Utilities.AddPart(rd);
            Utilities.Compose(target);

            var result = target.Render("http://www-d0.fnal.gov/Run2Physics/WWW/results/qcd.htm");
            var results = result.ToArray();

            var figTitles = from pvi in results
                            let md = FindMetadata<PivotMetadataString>(pvi, "Note Title")
                            from mdTitle in md
                            select mdTitle.Value;

            Assert.AreNotEqual(0, figTitles.Count(), "Expected some figure titles!");

            var title = figTitles.Where(t => t.StartsWith("High pT")).FirstOrDefault();
            Assert.IsNotNull(title, "Did not find the proper title!");
            Assert.IsTrue(title.Contains("cross"), "Title is '" + title + "' - not the full expected title!");
        }

        [TestMethod]
        public void TestForDescriptionSetting()
        {
            ScanMasterPage target = new ScanMasterPage();
            var laf = new LoadAFile() { theFileToLoad = new FileInfo("..\\..\\..\\t_DZEROPhysicsResultsPages\\QCD.html") };
            Utilities.AddPart(laf);
            var rd = new DummyRender();
            Utilities.AddPart(rd);
            Utilities.Compose(target);

            var result = target.Render("http://www-d0.fnal.gov/Run2Physics/WWW/results/qcd.htm");
            var results = result.ToArray();

            var descriptions = from r in results
                               select r.Description;
            Assert.IsTrue(descriptions.All(s => s.StartsWith("From the note titled ")), "Some of these guys don't have a note description starting with proper text.");
        }
    }
}
